package com.module.app.widget.keyboard.base;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

import androidx.annotation.ColorInt;
import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.module.base.R;

import java.lang.reflect.Field;

/**
 * @author bsnl_yanxuwen
 * @date 2020/3/25 15:40
 * Description :
 * 跟随键盘弹窗的弹框
 */
public class KeyboardHeightFragment extends DialogFragment {
    private Context mContext;
    private EditText editText;
    private View parent;
    private int keyboardHeight;
    private int keyboardLandscapeHeight;
    private int keyboardPortraitHeight;
    int mScreenHeight = 0;
    private boolean isShow;
    private int color;
    private boolean isClickKeyboard;//点击的时候是否只隐藏键盘

    public void setClickKeyboard(boolean clickKeyboard) {
        isClickKeyboard = clickKeyboard;
    }

    public interface Listener {
        void onComplete(View view);

        void onDismiss();
    }

    public Listener listener;

    public void setListener(Listener listener) {
        this.listener = listener;
    }


    public KeyboardHeightFragment() {

    }

    public static KeyboardHeightFragment newInstance(@LayoutRes int layoutId, @IdRes int editId, String defaultText) {
        return newInstance(layoutId, editId, defaultText, Color.parseColor("#00000000"));
    }

    public static KeyboardHeightFragment newInstance(@LayoutRes int layoutId, @IdRes int editId, String defaultText, @ColorInt int color) {
        KeyboardHeightFragment fragment = new KeyboardHeightFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("layoutId", layoutId);
        bundle.putInt("editId", editId);
        bundle.putString("defaultText", defaultText);
        bundle.putInt("color", color);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mContext = activity;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //主题设置动画无效，暂时不清楚，请用下面
        setStyle(DialogFragment.STYLE_NO_FRAME, R.style.keyboard_style);

    }


    /**
     * 设置状态栏透明
     */
    protected void setStatusBar(Window window) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && color != 0) {
            window.setStatusBarColor(color);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Window window = this.getDialog().getWindow();

        window.setDimAmount(0f);// 解决了无法去除遮罩问题
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.windowAnimations = R.style.keyboard_anim;
        window.setAttributes(lp);
        int layoutId = getArguments().getInt("layoutId");
        int editId = getArguments().getInt("editId");
        String defaultText = getArguments().getString("defaultText");
        color = getArguments().getInt("color");
        parent = inflater.inflate(layoutId, null);
        editText = parent.findViewById(editId);
        if (color != 0) {
            parent.setBackgroundColor(color);
        }
        setStatusBar(window);
        if (!TextUtils.isEmpty(defaultText)) {
            editText.setText(defaultText);
            editText.setSelection(editText.getText().length());
        }
        return parent;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (listener != null) {
            listener.onComplete(view);
        }

        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (getView() != null) {
                    if (mScreenHeight <= 0) {
                        Rect rect = new Rect();
                        getView().getWindowVisibleDisplayFrame(rect);
                        mScreenHeight = rect.bottom;
                    }
                    handleOnGlobalLayout();
                }
            }
        });
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isClickKeyboard) {
                    hideKeyboard();
                } else {
                    dismiss();
                }
            }
        });
        //防止部分手机弹不出来问题。所以手动在弹一次
        showKeyBoard();
    }

    @Override
    public void dismiss() {
        hideKeyboard();
        super.dismiss();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        if (listener != null) {
            listener.onDismiss();
        }
        super.onDismiss(dialog);
    }

    private void handleOnGlobalLayout() {

        Rect rect = new Rect();
        getView().getWindowVisibleDisplayFrame(rect);

        // REMIND, you may like to change this using the fullscreen size of the phone
        // and also using the status bar and navigation bar heights of the phone to calculate
        // the keyboard height. But this worked fine on a Nexus.
        int orientation = getScreenOrientation();
        keyboardHeight = mScreenHeight - rect.bottom;

        if (keyboardHeight == 0) {
            notifyKeyboardHeightChanged(0, orientation);
        } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            this.keyboardPortraitHeight = keyboardHeight;
            notifyKeyboardHeightChanged(keyboardPortraitHeight, orientation);
        } else {
            this.keyboardLandscapeHeight = keyboardHeight;
            notifyKeyboardHeightChanged(keyboardLandscapeHeight, orientation);
        }
    }

    private void notifyKeyboardHeightChanged(int height, int orientation) {
        if (height > 0) {
            if (!isShow) {
                isShow = true;
                //主题设置全屏的时候，才需要设置padding
//                parent.setPadding(parent.getPaddingLeft(),parent.getPaddingTop(),parent.getPaddingRight(),parent.getPaddingBottom() + keyboardHeight);
            }
        } else {
            if (isShow && !isClickKeyboard) {
                dismiss();
            }
        }
    }

    private int getScreenOrientation() {
        return mContext.getResources().getConfiguration().orientation;
    }

    public EditText getEditText() {
        return editText;
    }

    public void showKeyBoard() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    editText.requestFocus();
                    imm.showSoftInput(editText, 0);
                }
            }
        }, 50);

    }

    public void hideKeyboard() {
        try {
            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null && imm.isActive()) {
                imm.hideSoftInputFromWindow(getEditText().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**用于替代show ，因为show会抛异常Can not perform this action after onSaveInstanceState
     * 主要是改 ft.commit(); 改成  ft.commitAllowingStateLoss*/
    public void showAllowingStateLoss(@NonNull FragmentManager manager, @Nullable String tag) {
        try {
            Field dismissed = DialogFragment.class.getDeclaredField("mDismissed");
            dismissed.setAccessible(true);
            dismissed.set(this, false);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        try {
            Field shown = DialogFragment.class.getDeclaredField("mShownByMe");
            shown.setAccessible(true);
            shown.set(this, true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commitAllowingStateLoss();
    }

}
